package com.tnsw.noxnox;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.MediaController;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.VideoView;

import com.tnsw.coreutils.AsyncManager;
import com.tnsw.coreutils.http.THttpBase;
import com.tnsw.coreutils.http.THttpListener;
import com.tnsw.coreutils.http.THttpPost;
import com.tnsw.noxnox.db.DBManager;
import com.tnsw.noxnox.db.tables.DownloadProgress;
import com.tnsw.noxnox.dialog.FragmentDialogBuilder;
import com.tnsw.noxnox.dialog.FragmentDialogInterface;
import com.tnsw.noxnox.downloader.DLBase;
import com.tnsw.noxnox.downloader.DownloaderService;
import com.tnsw.noxnox.lab.LabWebViewFragment;
import com.tnsw.noxnox.settopbox.PortScanner;
import com.tnsw.noxnox.settopbox.PortScannerListener;
import com.tnsw.noxnox.streamer.StreamerService;

public class CatalogDetailFragment extends FragmentWithAdapter implements THttpListener, android.content.DialogInterface.OnClickListener, OnClickListener, OnErrorListener, OnPreparedListener, OnInfoListener, OnBufferingUpdateListener, PortScannerListener, FragmentDialogInterface {
	
	private String tag = "CatalogDetailFragment";
	private AsyncManager asyncManager;
	private DBManager dbm;
	private Context context;
	
	private DownloadProgress dp;
	private ViewGroup root;
	
	private Button btnPauseResume, btnPlay, btnDelete, btnAirplay;
	private Button btnVideo1, btnVideo2;
	private Button btnPauseEngine, btnResumeEngine;
	private VideoView videoView;
	private TextView tvTitle;
	private LinearLayout layoutButton;
	private RelativeLayout layoutVideo;
	
	private MediaController mc;
	private CatalogFragment cf;
	private int currentVideoPosition = 0;
	
	private ArrayList<String> ipAddressList;
	private FragmentDialogBuilder fd;
	private int dialogId;
	private int ipCount = 0;
	
	private Dialog currentDialog = null;
	
	public CatalogDetailFragment() {
		super();
		this.initialize();
	}
	
	public CatalogDetailFragment(Context context, FragmentPagerAdapter pagerAdapter, DownloadProgress dp, CatalogFragment cf) {
		super(context, pagerAdapter);
		this.initialize();
		this.context = context;
		this.dp = dp;
		this.cf = cf;
			
	}
	
	public void setCatalogFragment(CatalogFragment cf) {
		this.cf = cf;
	}
	
	public void setDownloadProgress(DownloadProgress dp) {
		this.dp = dp;
	}
	
	public void setFragmentPagerAdapter(FragmentPagerAdapter pagerAdapter) {
		this.adapter = pagerAdapter;
	}
	
	public void setContext(Context context) {
		this.context = context;
	}
	
	private void initialize() {
		this.asyncManager = AsyncManager.getInstance();
		this.dbm = DBManager.getInstance(this.context);
	}
	
	public static Fragment newInstance(Context context, FragmentPagerAdapter pagerAdapter, DownloadProgress dp, CatalogFragment cf) {
		Log.d("LabWebViewFragment", "newInstance()");
		CatalogDetailFragment f = new CatalogDetailFragment(context, pagerAdapter, dp, cf);
		return(f);
	}	
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		this.root = (ViewGroup) inflater.inflate(com.tnsw.noxnox.R.layout.catalog_detail, null);
		
		this.btnDelete = (Button) this.root.findViewById(R.id.catalogDetail_btnDelete);
		this.btnDelete.setOnClickListener(this);
		
		this.btnPauseResume = (Button) this.root.findViewById(R.id.catalogDetail_btnPauseResume);
		this.btnPauseResume.setOnClickListener(this);
		
		this.btnPlay = (Button) this.root.findViewById(R.id.catalogDetail_btnPlay);
		this.btnPlay.setOnClickListener(this);
		
		this.btnAirplay = (Button) this.root.findViewById(R.id.catalogDetail_btnAirplay);
		this.btnAirplay.setOnClickListener(this);
		
		this.btnVideo1 = (Button) this.root.findViewById(R.id.catalogDetail_btnVideo1);
		this.btnVideo1.setOnClickListener(this);
		
		this.btnVideo2 = (Button) this.root.findViewById(R.id.catalogDetail_btnVideo2);
		this.btnVideo2.setOnClickListener(this);
		
		this.btnPauseEngine = (Button) this.root.findViewById(R.id.catalogDetail_btnPauseEngine);
		this.btnPauseEngine.setOnClickListener(this);
		
		this.btnResumeEngine = (Button) this.root.findViewById(R.id.catalogDetail_btnResumeEngine);
		this.btnResumeEngine.setOnClickListener(this);
		
		this.tvTitle = (TextView) this.root.findViewById(R.id.catalogDetail_tvTitle);
		this.tvTitle.setText(this.dp.title);
		
		this.layoutButton = (LinearLayout) this.root.findViewById(R.id.catalogDetail_layoutButton);
		this.layoutVideo = (RelativeLayout) this.root.findViewById(R.id.layoutVideo);
		
		this.videoView = (VideoView) this.root.findViewById(R.id.catalogDetail_videoView);
		RelativeLayout.LayoutParams oldLayout = (RelativeLayout.LayoutParams) this.videoView.getLayoutParams();
		Log.d(tag, "original=" + oldLayout.alignWithParent);
		
		this.manageVideoView();
		Log.d(tag, "LayoutParam=" + this.videoView.getLayoutParams().getClass().getName() + ", " + this.videoView.getLayoutParams().toString());
		RelativeLayout.LayoutParams layout = (RelativeLayout.LayoutParams) this.videoView.getLayoutParams();
		
		
		this.refreshControlVisibility();
		
		return(root);
	}
	
	private void manageVideoView() {
		String url = "http://localhost:7779/media/play?id=" + String.valueOf(this.dp.primarykey);
		//url = "http://172.16.50.1:8080/examples/1.webm";
		Uri uri = Uri.parse(url);

		this.videoView.setOnErrorListener(this);
		this.videoView.setOnPreparedListener(this);
		//this.videoView.setVideoURI(uri);
		//this.videoView.setVideoPath(this.dp.filename);
		
		
		//this.videoView.setVideoPath(this.dp.filename);
		
		
		this.mc = new MediaController(this.context);
		this.videoView.setMediaController(this.mc);
		//this.mc.show();
		
		//this.videoView.start();
	}
	
	private void recreateVideoview() {
		Log.d(tag, "recreating new VideoView");
		RelativeLayout.LayoutParams oldLayout = (RelativeLayout.LayoutParams) this.videoView.getLayoutParams();
		Log.d(tag, "old=" + oldLayout.alignWithParent);
		oldLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		oldLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		oldLayout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		oldLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		
		RelativeLayout.LayoutParams newLayout = new RelativeLayout.LayoutParams(this.videoView.getLayoutParams());
		newLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		newLayout.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
		newLayout.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		newLayout.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
		Log.d(tag, "new=" + newLayout.alignWithParent);
		
		
		this.videoView.stopPlayback();
		this.videoView.setVisibility(View.GONE);
		this.layoutVideo.removeView(this.videoView);
		
		this.videoView = new VideoView(this.context);
		String url = "http://localhost:7779/media/play?id=" + String.valueOf(this.dp.primarykey);
		//url = "http://172.16.50.1:8080/examples/1.webm";
		Uri uri = Uri.parse(url);
		this.videoView.setVideoURI(uri);
		this.videoView.setOnErrorListener(this);
		this.videoView.setOnPreparedListener(this);
		this.videoView.setMediaController(this.mc);
		
		//this.mc.show(5000);
		this.layoutVideo.addView(this.videoView);
		
		this.videoView.start();
		this.videoView.setLayoutParams(newLayout);
		Log.d(tag, "done creating VideoView");
	}
	
	private void refreshControlVisibility() {
		/*
		if (this.dp.status == 2) {
			this.btnPauseResume.setVisibility(View.GONE);
			this.btnStop.setVisibility(View.GONE);

		}
		*/

	}
	
	private void deleteVideo() {
		try {
			File f = new File(dp.filename);
			f.delete();
			Log.d(tag, "deleted file=" + dp.filename);
			
			f = new File(dp.thumbnail_filename);
			f.delete();
			Log.d(tag, "delted thumbnail=" + dp.thumbnail_filename);
			
			this.dbm.deleteDownloadProgress(dp);	
			Log.d(tag, "Deleted dp=" + dp.primarykey);
			this.cf.doRefresh();
			this.cf.returnHome();
			
		} catch (Exception e) {
			Log.d(tag, "deleteVideo(dp=" + dp.primarykey + ") - " + e.toString(), e);
		}
		
	}
	
	private String getUrl() {
		String url = "";
		
		if (THttpBase.getWiFiIPAddress(this.context).equals("0.0.0.0")) {
			url = "http://localhost:7779/";
		} else {
			url = "http://" + THttpBase.getWiFiIPAddress(this.context) + ":7779/";
		}
		
		url = url + "media/play?id=" + this.dp.primarykey;
		
		return(url);
	}
	
	@Override
	public void onClick(View v) {
		// id=65, 92 is workable
		
		if (v == this.btnDelete) {
			this.deleteVideo();
			
		} else if (v == this.btnPauseResume) {  // to pause of resume VideoView
			if (this.btnPauseResume.getText().toString().equals("Resume")) {
				// going to resume
				
				this.videoView.seekTo(this.currentVideoPosition);
				this.videoView.start();
				this.btnPauseResume.setText("Pause");
				
			} else {
				// going to pause
				this.videoView.pause();
				this.currentVideoPosition = this.videoView.getCurrentPosition();
				this.btnPauseResume.setText("Resume");
			}
			
		} else if (v == this.btnPlay) {
			String url = "http://localhost:7779/media/play?id=" + String.valueOf(this.dp.primarykey);
			Uri uri = Uri.parse(url);
			
			//this.videoView.setVideoURI(uri);
			this.videoView.setVideoPath(this.dp.filename);
			this.videoView.start();
			
			
			
		} else if (v == this.btnAirplay) {
			this.ipCount = 0;
			PortScanner scanner = new PortScanner(this.context);
			scanner.setListener(this);
			try {
				scanner.scan();	
			} catch (Exception e) {
				
			}
						
			this.fd = new FragmentDialogBuilder(this.context, this);			
			fd.setStyle(DialogFragment.STYLE_NORMAL, fd.getTheme());
			fd.setCancelable(false);
			fd.show(this.getFragmentManager(), "0");
			
			
		} else if (v == this.btnVideo1) {
			THttpPost p = new THttpPost(context, "http://localhost:7778/stb/play");
			ArrayList<NameValuePair> a = new ArrayList<NameValuePair>();
			
			StreamerService ss = StreamerService.getInstance();
			String mediaUrl = "";
			if (ss == null) {
				Log.e(tag, "Cannot send stream cause StreamService is not running");
			} else {
				mediaUrl = ss.getMediaPlayUrl(this.dp.primarykey);
			}
			
			a.add(new BasicNameValuePair("url", mediaUrl));
			try {
				p.setEntity(new UrlEncodedFormEntity(a));
				p.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "0");				
			} catch (Exception e) {
				Log.e(tag, "Airplay2 - " + e.toString(), e);
			}

			
		} else if (v == this.btnVideo2) {
			
			//this.videoView.stopPlayback();
						
			Uri uri = Uri.parse("http://localhost:7779/media/play?id=92");
			/*
			this.videoView.setVideoURI(uri);			
			this.videoView.start();
			Log.d(tag, "Playing id=92");
			*/
			
			Button b1 = new Button(this.context);
			b1.setText("Hello");
			//this.layoutButton.addView(b1);
			
			Log.d(tag, "Here!!");
			VideoView vv = new VideoView(this.context);
			vv.setVideoPath(this.dp.filename);
			vv.start();
			this.layoutButton.addView(vv);
			
			
		} else if (v == this.btnPauseEngine) {
			DownloaderService ds = DownloaderService.getInstance(this.context);
			DLBase dl = ds.getDLBase(this.dp.primarykey);
			if (dl != null) {
				dl.pause();
				Log.d(tag, "Paused engine");
			}
			
		} else if (v == this.btnResumeEngine) {
			DownloaderService ds = DownloaderService.getInstance(this.context);
			DLBase dl = ds.getDLBase(this.dp.primarykey);
			if (dl != null) {
				dl.resume();
				Log.d(tag, "Resumed engine");
			}
		}
	
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		Log.d(tag, "onError(what=" + what + ", extra=" + extra + ")");
		//this.currentVideoPosition = this.videoView.getCurrentPosition();
		Log.d(tag, "currentPosition=" + this.videoView.getCurrentPosition());
		
		this.recreateVideoview();
		
		return true;
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		Log.d(tag, "onPrepared()");
		//mp.start();
		Log.d(tag, "played....");
		this.btnPauseResume.setText("Pause");
		mp.setOnBufferingUpdateListener(this);
		mp.setOnInfoListener(this);
		
	
	}

	@Override
	public void onBufferingUpdate(MediaPlayer mp, int percent) {
		Log.d(tag, "onBufferingUpdate(percent=" + percent + ")");
	}

	@Override
	public boolean onInfo(MediaPlayer mp, int what, int extra) {
		Log.d(tag, "onInfo(what=" + what + ", extra=" + extra + ")");
		Log.d(tag, "onInfo-currentPosition=" + this.videoView.getCurrentPosition());
		return false;
	}

	@Override
	public void onClick(DialogInterface dialog, int which) {
		Log.d(tag, "onClick:dialog=" + dialog.getClass().getName() + ", which=" + which);
		String selectedIP = this.ipAddressList.get(which);
		
		StreamerService ss = StreamerService.getInstance();
		if (ss != null) {
			int primarykey = this.dp.primarykey;
			String requestUrl = "http://" + selectedIP + ":7778/stb/play?id=" + String.valueOf(primarykey);
			THttpPost p = new THttpPost(this.context, requestUrl);
			p.setListener(this);
			p.setSessionName("play");
			
			ArrayList<NameValuePair> a = new ArrayList<NameValuePair>();
			String mediaUrl = ss.getMediaPlayUrl(primarykey);
			a.add(new BasicNameValuePair("url", mediaUrl));
			
			try {
				p.setEntity(new UrlEncodedFormEntity(a));
				p.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, "0");
			} catch (Exception e) {
				Log.e(tag, "Error on trying to send command to TV - " + e.toString(), e);
			}
			
		}		
	}

	@Override
	public void onProgressUpdate(THttpBase sender, Integer[] values) {
		
	}

	@Override
	public void onPostExecute(THttpBase sender, Long result) {
		
	}

	@Override
	public void onNewLineFetchBG(THttpBase sender, String line) {
		
	}

	@Override
	public void onReceiveResponseBG(THttpBase sender) {
		
	}

	@Override
	public void onBinaryReadBG(THttpBase sender, byte[] b) {
		
	}

	@Override
	public Dialog onCreateDialog(Bundle savedInstanceState) {
		AlertDialog.Builder dialog = null;
		dialog = new AlertDialog.Builder(this.context);
		
		if (this.dialogId == 0) {
			
			dialog.setTitle("Please wait..");
			dialog.setPositiveButton("Rescan", this);
			dialog.setCancelable(false);
			
		} else if (this.dialogId == 1){
			dialog.setTitle("Choose TV");
			if (this.ipAddressList != null) {
				String[] ips = new String[this.ipAddressList.size()];
				int i;
				for (i = 0; i < ips.length; i++) {
					ips[i] = this.ipAddressList.get(i);
				}
				dialog.setItems(ips, this);
			}
			
		}
		
		this.currentDialog = dialog.create();
		return(this.currentDialog);
	}

	@Override
	public void onComplete(PortScanner sender, ArrayList<String> ipAddressList) {
		Log.d(tag, "onCompleted:");
		for (String ipAddress : ipAddressList) {
			Log.d(tag, "OK:" + ipAddress);
		}
		
		this.ipAddressList = ipAddressList;
		
		Log.d(tag, "class=" + this.getFragmentManager().findFragmentByTag("0").getClass().getName());
		FragmentDialogBuilder fd = (FragmentDialogBuilder) this.getFragmentManager().findFragmentByTag("0");
		fd.dismiss();
		
		this.dialogId = 1;
		fd.setCancelable(true);
		fd.show(this.getFragmentManager(), "0");		
	}

	@Override
	public void onSingleCompleted(PortScanner sender, String ipAddress, boolean isOK, String detail) {
		this.ipCount += 1;
		Log.d(tag, "onSingleCompleted:" + ipAddress + ", isOK=" + isOK + ", detail=" + detail);
		if (this.currentDialog != null) {
			this.currentDialog.setTitle("Please wait..(" + String.valueOf(this.ipCount) + ")");
			Log.d(tag, "ipCount=" + this.ipCount);
		} else {
			Log.w(tag, "this.dialog == null!!");
		}
		
	}
	
}
